package org.ko.core.websupport.log.spring;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ko.core.websupport.log.Log;
import org.ko.core.websupport.log.LogWorker;
import org.ko.core.websupport.log.impl.LogUitls;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/** 
 * 	
 * @author 	<a href="mailto:ketayao@gmail.com">ketayao</a>
 * Version  2.1.0
 * @since   2013-5-3 下午4:37:11 
 */

public class LogInterceptor extends HandlerInterceptorAdapter {
	protected final static Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class); 
	
	private LogWorker logWorker;
	
	/**   
	 * 将request存入LogUitl中的LOCAL_REQUEST。
	 * @param request
	 * @param response
	 * @param handler
	 * @return
	 * @throws Exception  
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)  
	 */
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		LogUitls.putRequest(request);
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		if (!(handler instanceof HandlerMethod)) {
			return ;
		}
		
		final HandlerMethod handlerMethod = (HandlerMethod)handler;
		Method method = handlerMethod.getMethod();
		
		final Log log = method.getAnnotation(Log.class);
		final HttpServletRequest threadReq = LogUitls.getRequest();
		if (log != null) {
			try{
				logWorker.log(log.message(), threadReq, log.params(), log.level(),log.category());
			}catch(Exception e){
				e.printStackTrace();
			}
			
			/**
			 * 新开线程的哈，有可能（50%的概率）造成在浏览器刷新页面时，url上面的参数不会绑定到 model
			 * 具体原因还有待考查
			 * 
			 * 现在就直接在原来线程进行日志的保存工作，影响不大
			 * 
			 * on 2014-10-13
			 */
//			// 另起线程异步操作
//			new Thread(new Runnable() {
//				
//				@Override
//				public void run() {
//					try {
//						LogLevel lastLogLevel = logWorker.getRootLogLevel();
//						
//						// 先对自定义包等级做判断
//						Map<String, LogLevel> customLogLevel = logWorker.getCustomLogLevel();
//						if (!customLogLevel.isEmpty()) {
//							Class<?> clazz = handlerMethod.getBean().getClass();
//							String packageName = clazz.getPackage().getName();
//							
//							Set<String> keys = customLogLevel.keySet();
//							for (String key : keys) {
//								if (packageName.startsWith(key)) {
//									lastLogLevel = customLogLevel.get(key);
//									break;
//								}
//							}
//						}
//						if (log.override()) {
//							logWorker.log(log.message(), threadReq, log.params(), log.level(),log.category());
//						} else {
//							// 不覆盖，参考方法的日志等级是否大于等于最终的日志等级
//							if (!log.override() && log.level().compareTo(lastLogLevel) >= 0 ) {
//								logWorker.log(log.message(), threadReq,log.params(), log.level(),log.category());
//							}
//						}
//					} catch (Exception e) {
//						e.printStackTrace();
//					} 
//				}
//			}).start();
			
		}
		
	}
	
	/**
	 * 清除LogUitl中的LOCAL_REQUEST。
	 * @param request
	 * @param response
	 * @param handler
	 * @param ex
	 * @throws Exception  
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterCompletion(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)  
	 */
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		LogUitls.removeRequest();
	}

	public LogWorker getLogWorker() {
		return logWorker;
	}

	public void setLogWorker(LogWorker logWorker) {
		this.logWorker = logWorker;
	}
}
